package org.lego4j.policy;

import java.util.ArrayList;
import java.util.List;

import org.lego4j.IRetryOnExceptionPolicy;

/**
 * Will retry a maximum number of times if the exception thrown has a predefined exception type.  
 *
 * @author <a href="alexguev@gmail.com">Alexei Guevara</>
 * @version $Revision:$ updated on $Date:$ by $Author:$
 */
public class RetryMaxNumberOfTimes implements IRetryOnExceptionPolicy {
    
    private final List<Class<? extends Exception>> exTypes;
    private final int maxRetries;
    private final long delayInMillis;

    /**
     * @param exTypes The predefined exception types.
     * @param maxRetries The maximum numbers of retries to attempt.
     * @param delayInMillis The time to wait before retrying, in milliseconds.
     */
    public RetryMaxNumberOfTimes(List<Class<? extends Exception>> exTypes, int maxRetries, long delayInMillis) {
        this.exTypes = new ArrayList<Class<? extends Exception>>(exTypes.size());
        for (Class<? extends Exception> exType : exTypes) {
        	this.exTypes.add(exType);	
		}
        
        this.maxRetries = maxRetries;
        this.delayInMillis = delayInMillis;
    }

	/**
     * {@inheritDoc}
     */
    public boolean isExceptionRecoverable(Throwable e) {
    	for (Class<? extends Exception> clazz : this.exTypes) {
    		if (clazz.isInstance(e)) {
    			return true;	
    		}
		}
    	return false;
    }

    
    /**
     * {@inheritDoc}
     */
    public long nextDelay(long startTime, int numPreviousRetries) {
        if ( numPreviousRetries < this.maxRetries ) {
            return this.delayInMillis;
        }
        
        return -1;
    }

}
